﻿using System.Diagnostics;
using System.IO;
using System.Windows;
using System.Windows.Navigation;
using System.Windows.Threading;
using System.Xml.Linq;
using Microsoft.Win32;

namespace VideoToGif;

/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    private bool needNotifyError;

    public MainWindow()
    {
        InitializeComponent();

        ReadUserData();
    }

    /// <summary>
    /// 点击进行Gif生成
    /// </summary>
    private void OnClickConfirmBtn(object sender, RoutedEventArgs e)
    {
        needNotifyError = true;
        string gifOutputPath = GifOutputTextBox.Text + "/" + GifNameTextBox.Text + ".gif";
        string arguments = @$"-i {VideoInputTextBox.Text} -y {gifOutputPath}";

        Process p = new Process(); //建立外部调用进程
        //要调用外部程序的绝对路径
        p.StartInfo.FileName = FFmpegTextBox.Text;
        p.StartInfo.Arguments = arguments;

        p.StartInfo.UseShellExecute = false; //不使用操作系统外壳程序启动线程(一定为FALSE,详细的请看MSDN)
        p.StartInfo.RedirectStandardError =
            true; //把外部程序错误输出写到StandardError流中(这个一定要注意,FFMPEG的所有输出信息,都为错误输出流,用StandardOutput是捕获不到任何消息的...)
        p.StartInfo.CreateNoWindow = true; //不创建进程窗口

        string explorerOpenFolder = GifOutputTextBox.Text;
        p.ErrorDataReceived += (o, args) =>
        {
            Console.WriteLine(args.Data);
            if (args.Data != null && needNotifyError && args.Data.Contains("Error"))
            {
                MessageBox.Show("Gif生成失败!", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                needNotifyError = false;
            }

            if (args.Data != null && args.Data.Contains($"out#0/gif"))
            {
                Process.Start("explorer.exe", explorerOpenFolder);
            }
        }; //外部程序(这里是FFMPEG)输出流时候产生的事件,这里是把流的处理过程转移到下面的方法中,详细请查阅MSDN
        p.Start(); //启动线程
        p.BeginErrorReadLine(); //开始异步读取
        p.WaitForExit(); //阻塞等待进程结束
        p.Close(); //关闭进程
        p.Dispose(); //释放资源
    }

    /// <summary>
    /// 点击选中视频文件
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void OnClickVideoFileBtn(object sender, RoutedEventArgs e)
    {
        var fileDialog = new OpenFileDialog
        {
            Title = "选择视频文件",
            InitialDirectory = VideoInputTextBox.Text
        };

        if (fileDialog.ShowDialog() != true)
            return;

        string fileName = fileDialog.FileName;
        VideoInputTextBox.Text = fileName;
        
        SaveXmlDoc(VideoInputTextBox.Text, GifOutputTextBox.Text, FFmpegTextBox.Text);
    }

    /// <summary>
    /// 点击选中Gif生成的目录
    /// </summary>
    private void OnClickGifOutputFolderBtn(object sender, RoutedEventArgs e)
    {
        var folderDialog = new OpenFolderDialog
        {
            Title = "选择Gif输出目录",
            InitialDirectory = GifOutputTextBox.Text
        };

        if (folderDialog.ShowDialog() != true)
        {
            return;
        }

        string folderName = folderDialog.FolderName;
        GifOutputTextBox.Text = folderName;

        SaveXmlDoc(VideoInputTextBox.Text, GifOutputTextBox.Text, FFmpegTextBox.Text);
    }

    /// <summary>
    /// 点击选择FFmpeg文件
    /// </summary>
    private void OnClickFFmpegFolderBtn(object sender, RoutedEventArgs e)
    {
        var fileDialog = new OpenFileDialog
        {
            Title = "选择FFmpeg文件",
            InitialDirectory = FFmpegTextBox.Text
        };

        if (fileDialog.ShowDialog() != true)
            return;

        string fileName = fileDialog.FileName;
        FFmpegTextBox.Text = fileName;
        
        SaveXmlDoc(VideoInputTextBox.Text, GifOutputTextBox.Text, FFmpegTextBox.Text);
    }

    /// <summary>
    /// 点击打开FFmpeg网页下载页面
    /// </summary>
    private void OnClickOpenFFmpegDownloadWebPage(object sender, RequestNavigateEventArgs e)
    {
        Process.Start(new ProcessStartInfo(e.Uri.AbsoluteUri) {UseShellExecute = true});
        e.Handled = true;
    }
    
    private void ReadUserData()
    {
        XDocument xDoc = null;
        if (File.Exists("UserData.xml"))
        {
            xDoc = XDocument.Load("UserData.xml");
        }
        if (xDoc == null)
        {
            xDoc = SaveXmlDoc();
        }

        VideoInputTextBox.Text = xDoc.Root.Element("VideoFile").Value;
        GifOutputTextBox.Text = xDoc.Root.Element("GifFolder").Value;
        FFmpegTextBox.Text = xDoc.Root.Element("FFmpegPath").Value;
    }

    private XDocument SaveXmlDoc(string videoFile = "", string gifFoler = "", string FFmpegPath = "")
    {
        XDocument xDoc = new XDocument();
        xDoc.Add(new XElement("Root"));
        XElement videoFilePathEle = new XElement("VideoFile",videoFile);
        XElement gifFolderPathEle = new XElement("GifFolder", gifFoler);
        XElement ffmpegPathEle = new XElement("FFmpegPath", FFmpegPath);
        xDoc.Root.Add(videoFilePathEle);
        xDoc.Root.Add(gifFolderPathEle);
        xDoc.Root.Add(ffmpegPathEle);

        xDoc.Save("UserData.xml");
        return xDoc;
    }
}